home *** CD-ROM | disk | FTP | other *** search
- /*
- this file was changed or created for the DOS32 library for DJGPP on 5.10.1996
- new created files are copyright 1996 by C.Lageman, see docs.doc for details
- */
- /*
- This file contains the exception handlers and interrupts needed for
- the dos32 library.
-
- problem: Unter the dos32 environment the IRQs 0-7 and expections 8-15
- use the same interrupt handlers, so we must check in these
- expections, if the called handler is really an expection or
- just an IRQ. In the second case the int is chained down to the
- old handler.
- Of course, this can cause a noticeable (?) slowdown of the machine,
- so installing these handlers or just only the expection 8 (which
- blocks the timer IRQ) can be disabled by __crt0_startup_flags.
- problem: should the exit proc called on an exception program abort
- rather than directly exiting ?
- */
- .file "exceptn.s"
- .text
-
-
- /*
- this handler should be aligned 16, because it's called very often
- */
- .align 16
- handler8:
- pushl %eax
- movl $___dos32_oldints+0xf*8,%eax
- call testirq
- pushl %eax
- movl $msgexp8,%eax
- jmp saveregs
- handler9:
- pushl %eax
- movl $___dos32_oldints+9*8,%eax
- call testirq
- sub $4,%esp
- pushl %eax
- movl $msgexp9,%eax
- jmp saveregs
- handlera:
- pushl %eax
- movl $___dos32_oldints+0xa*8,%eax
- call testirq
- pushl %eax
- movl $msgexpa,%eax
- jmp saveregs
- handlerb:
- pushl %eax
- movl $___dos32_oldints+0xb*8,%eax
- call testirq
- pushl %eax
- movl $msgexpb,%eax
- jmp saveregs
- handlerc:
- pushl %eax
- movl $___dos32_oldints+0xc*8,%eax
- call testirq
- pushl %eax
- movl $msgexpc,%eax
- jmp saveregs
- handlerd:
- pushl %eax
- movl $___dos32_oldints+0xd*8,%eax
- call testirq
- pushl %eax
- movl $msgexpd,%eax
- jmp saveregs
- handlere:
- pushl %eax
- movl $___dos32_oldints+0xe*8,%eax
- call testirq
- pushl %eax
- movl $msgexpe,%eax
- jmp saveregs
- handler0:
- pushl %eax
- movl $msgexp0,%eax
- jmp saveregs
- handler2:
- pushl %eax
- movl $msgexp2,%eax
- jmp saveregs
- handler4:
- pushl %eax
- movl $msgexp4,%eax
- jmp saveregs
- handler5:
- pushl %eax
- movl $msgexp5,%eax
- jmp saveregs
- handler6:
- pushl %eax
- movl $msgexp6,%eax
- jmp saveregs
- handler7:
- pushl %eax
- movl $msgexp7,%eax
-
- saveregs:
- pushl %ds
- cs
- movw ___dos32_ds,%ds
- movl %eax,expmsg
- /*
- get old ds & save
- */
- popl %eax
- movl %eax,regstore+16
- /*
- restore eax
- */
- popl %eax
- movl %esp,esptemp
- movw %ss,sstemp
- pushl %ds
- popl %ss
- movl $regstoreend,%esp
- pusha
- pushl %gs
- pushl %fs
- pushl %es
- movl esptemp,%esp
- movw sstemp,%ss
- popl regstore+4
- popl regstore
- movl %esp,regstore+12
- popl regstoreend
- movl %ss,regstore+8
-
-
- movl $expmask,%ecx
- call dumpmsg
- movl expmsg,%ecx
- call dumpmsg
-
- cld
- movl $regaddr,%esi
- movl $regstore,%edx
- xorl %ecx,%ecx
- regs2hex:
- movl (%esi),%edi
- movl (%edx),%ebx
- orl %edi,%edi
- jz hexdone
- addl $4,%edx
- addl $4,%esi
- movb $8,%cl
- inner:
- xorl %eax,%eax
- shldl $4,%ebx,%eax
- movb hexstring(%eax),%al
- ds
- stosb
- shl $4,%ebx
- decl %ecx
- jnz inner
-
- jmp regs2hex
- hexdone:
- movl $regmask,%ecx
- call dumpmsg
- leaveme:
- movw $0x4c01,%ax
- int $0x21
-
- .align 16
- testirq:
- /*
- eax - address of pointer to old int
- stack:
- esp+16 [ app eflags ]
- esp+12 [ XXXX | app cs ]
- esp+8 [ app eip ]
- esp+4 [ eax ]
- esp [ caller eip ]
- */
- pushl %eax
- inb $0x21,%al
- outb %al,$0x21
- movb $0x40,%al
- outb %al,$0x20
- movb $0x0B,%al
- outb %al,$0x20
- inb $0x20,%al
- orb %al,%al
- popl %eax
- jz 1f
-
- cs
- pushl 4(%eax)
- cs
- pushl (%eax)
- /*
- stack:
- esp+26 [ app eflags ]
- esp+24 [ XXXX | app cs ]
- esp+16 [ app eip ] <--- at this point esp will be after lret
- esp+12 [ eax ] removed by lret $8
- esp+8 [ caller eip ] removed by lret $8
- esp+4 [ XXXX | int cs ]
- esp [ int eip ]
- */
- movl 12(%esp),%eax
- lret $8
- 1:
- movl 4(%esp),%eax
- ret $8
-
- dumpmsg:
- movb $6,%ah
- 1: movb (%ecx),%dl
- orb %dl,%dl
- jz 2f
- incl %ecx
- int $0x21
- jmp 1b
- 2: ret
-
-
- /*
- bios ctrl-break
- */
- int1b:
- pushl %ds
- cs
- movw ___dos32_ds,%ds
- testb $1,___dos32_cbreak_mode
- jz cbreak_exit
- testb $2,___dos32_cbreak_mode
- jz 1f
- movb $1,___dos32_cbreak_counter
- 1:
- popl %ds
- iret
-
- cbreak_exit:
- movl $cbreakmsg,%ecx
- call dumpmsg
- jmp leaveme
-
- /*
- dos ctrl-c / ctrl - break
- this is faked by just using the identical int1b handler
- int23:
- jmp int1b
- */
-
- /*
- critical error handler with 3 retries (remove retrys ?)
- */
- int24:
- testb $0x80,%ah
- jnz fail_int24
- pushl %ds
- pushl %esi
- cs
- movw ___dos32_ds,%ds
- cmpb errordrive,%al
- movl $error_retries,%esi
- je 1f
- movb %al,errordrive
- movb $0,(%esi)
- 1: incb (%esi)
- cmpb $3,(%esi)
- popl %esi
- popl %ds
- ja fail_int24
- movb $1,%al
- clc
- lret
- fail_int24:
- movb $3,%al
- clc
- lret
-
- .data
- .lcomm esptemp,4
- .lcomm sstemp,2
- errordrive:
- .byte 0xff
- .lcomm error_retries,1
-
- hexstring:
- .ascii "0123456789ABCDEF"
-
- .lcomm regstore,68
- .set regstoreend, regstore + 64
-
- .lcomm expmsg,4
-
- regaddr:
- .long reg1,reg2,reg3,reg4,reg5,reg6,reg7,reg8,reg14
- .long reg13,reg15,reg10,reg10,reg12,reg11,reg9,reg16,0
-
- msgexp0:
- .asciz "0 - division by zero"
- msgexp2:
- .asciz "2 - non maskable interrupt"
- msgexp4:
- .asciz "4 - overflow"
- msgexp5:
- .asciz "5 - bound range exceeded$"
- msgexp6:
- .asciz "6 - invalib opcode"
- msgexp7:
- .asciz "7 - coprocessor not aviable"
- msgexp8:
- .asciz "8 - double fault"
- msgexp9:
- .asciz "9 - coprocessor segment overrun"
- msgexpa:
- .asciz "10 - invalid TSS"
- msgexpb:
- .asciz "11 - segment not present"
- msgexpc:
- .asciz "12 - stack exception"
- msgexpd:
- .asciz "13 - general protection fault"
- msgexpe:
- .asciz "14 - page fault"
-
-
- expmask:
- .asciz "exception "
- regmask:
- .byte 13,10
- .ascii "CS:EIP - "
- reg1:
- .ascii "MISSING!:"
- reg2:
- .ascii "MISSING! SS:ESP - "
- reg3:
- .ascii "MISSING!:"
- reg4:
- .ascii "MISSING!"
- .byte 13,10
- .ascii "DS: "
- reg5:
- .ascii "MISSING! ES: "
- reg6:
- .ascii "MISSING! FS: "
- reg7:
- .ascii "MISSING! GS: "
- reg8:
- .ascii "MISSING!"
- .byte 13,10
- .ascii "EAX: "
- reg9:
- .ascii "MISSING! EBX: "
- reg10:
- .ascii "MISSING! ECX: "
- reg11:
- .ascii "MISSING! EDX: "
- reg12:
- .ascii "MISSING!"
- .byte 13,10
- .ascii "ESI: "
- reg13:
- .ascii "MISSING! EDI: "
- reg14:
- .ascii "MISSING! EBP: "
- reg15:
- .ascii "MISSING! FLAGS: "
- reg16:
- .ascii "MISSING!"
- .byte 13,10
- .ascii "Program abort !"
- .byte 13,10,0
-
- cbreakmsg:
- .ascii "Exit due to <CTRL-BREAK>"
- .byte 13,10,0
-
- .global ___dos32_new_ints
- ___dos32_new_ints:
- .byte 0x1b
- .long int1b
- .byte 0x23
- .long int1b
- .byte 0x24
- .long int24
- .byte 0x0
- .long handler0
- .byte 0x2
- .long handler2
- .byte 0x4
- .long handler4
- .byte 0x5
- .long handler5
- .byte 0x6
- .long handler6
- .byte 0x7
- .long handler7
- .byte 0x9
- .long handler9
- .byte 0xa
- .long handlera
- .byte 0xb
- .long handlerb
- .byte 0xc
- .long handlerc
- .byte 0xd
- .long handlerd
- .byte 0xe
- .long handlere
- .byte 0x8
- .long handler8
- .byte 0xff
- /*
- ******************** end of exceptn.s **********************************
- */
-